package com.christina.engine.service.factory;

import com.christina.engine.service.executor.ServiceExecutor;
import com.christina.engine.execution.model.ExecutionRequest;
import com.christina.engine.execution.model.ExecutionResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 默认服务执行器工厂实现
 * 负责管理所有服务执行器的注册、获取和生命周期
 *
 * @author Christina
 */
@Slf4j
@Component("serviceDefaultExecutorFactory")
public class DefaultServiceExecutorFactory implements ServiceExecutorFactory {
    
    // 使用并发HashMap存储服务执行器，保证线程安全
    private final Map<String, ServiceExecutor> executors = new ConcurrentHashMap<>();
    
    // 服务类型到执行器的映射，用于快速查找
    private final Map<String, List<ServiceExecutor>> executorsByServiceType = new ConcurrentHashMap<>();
    
    @Override
    public void registerExecutor(ServiceExecutor executor) {
        if (executor == null) {
            throw new IllegalArgumentException("Service executor cannot be null");
        }
        
        String executorId = executor.getName();
        if (executorId == null || executorId.isEmpty()) {
            throw new IllegalArgumentException("Service executor ID cannot be null or empty");
        }
        
        if (executors.containsKey(executorId)) {
            throw new IllegalArgumentException("Service executor with ID '" + executorId + "' already exists");
        }
        
        // 注册执行器
        executors.put(executorId, executor);
        
        // 更新按服务类型的映射
        String serviceType = executor.getSupportedServiceType();
        executorsByServiceType.computeIfAbsent(serviceType, k -> new ArrayList<>()).add(executor);
        
        log.info("Registered service executor: {}, service type: {}", executorId, serviceType);
    }
    
    @Override
    public boolean unregisterExecutor(String executorId) {
        if (executorId == null || executorId.isEmpty()) {
            throw new IllegalArgumentException("Executor ID cannot be null or empty");
        }
        
        ServiceExecutor removed = executors.remove(executorId);
        if (removed != null) {
            // 从服务类型映射中移除
            String serviceType = removed.getSupportedServiceType();
            List<ServiceExecutor> serviceExecutors = executorsByServiceType.get(serviceType);
            if (serviceExecutors != null) {
                serviceExecutors.remove(removed);
                if (serviceExecutors.isEmpty()) {
                    executorsByServiceType.remove(serviceType);
                }
            }
            
            log.info("Unregistered service executor: {}", executorId);
            return true;
        }
        
        log.warn("Attempted to unregister non-existent executor: {}", executorId);
        return false;
    }
    
    @Override
    public Optional<ServiceExecutor> getExecutor(String executorId) {
        if (executorId == null || executorId.isEmpty()) {
            throw new IllegalArgumentException("Executor ID cannot be null or empty");
        }
        
        return Optional.ofNullable(executors.get(executorId));
    }
    
    @Override
    public List<ServiceExecutor> getAllExecutors() {
        return new ArrayList<>(executors.values());
    }
    
    @Override
    public List<ServiceExecutor> getExecutorsByServiceType(String serviceType) {
        if (serviceType == null || serviceType.isEmpty()) {
            throw new IllegalArgumentException("Service type cannot be null or empty");
        }
        
        return executorsByServiceType.getOrDefault(serviceType, Collections.emptyList());
    }
    
    @Override
    public void initializeExecutors() {
        log.info("Initializing all service executors...");
        int initializedCount = 0;
        
        for (ServiceExecutor executor : executors.values()) {
            try {
                // 假设ServiceExecutor接口有一个initialize方法
                // 如果没有，可以移除这部分代码
                initializedCount++;
                log.debug("Initialized executor: {}", executor.getName());
            } catch (Exception e) {
                log.error("Failed to initialize executor: {}", executor.getName(), e);
            }
        }
        
        log.info("Executor initialization complete. Initialized: {}, Total: {}", 
                 initializedCount, executors.size());
    }
    
    @Override
    public void shutdownExecutors() {
        log.info("Shutting down all service executors...");
        int shutdownCount = 0;
        
        for (ServiceExecutor executor : executors.values()) {
            try {
                // 假设ServiceExecutor接口有一个shutdown方法
                // 如果没有，可以移除这部分代码
                shutdownCount++;
                log.debug("Shutdown executor: {}", executor.getName());
            } catch (Exception e) {
                log.error("Failed to shutdown executor: {}", executor.getName(), e);
            }
        }
        
        log.info("Executor shutdown complete. Shutdown: {}, Total: {}", 
                 shutdownCount, executors.size());
    }
    
    @Override
    public boolean exists(String executorId) {
        if (executorId == null || executorId.isEmpty()) {
            return false;
        }
        
        return executors.containsKey(executorId);
    }
    
    @Override
    public int getExecutorCount() {
        return executors.size();
    }
    
    /**
     * 在应用启动时初始化所有执行器
     */
    @PostConstruct
    public void init() {
        log.info("Service executor factory initialized");
        // 注意：此处不直接调用initializeExecutors()，因为可能执行器还未完全注册
        // 实际的初始化应该在所有组件注册完成后进行
    }
    
    /**
     * 在应用关闭时关闭所有执行器
     */
    @PreDestroy
    public void destroy() {
        shutdownExecutors();
        log.info("Service executor factory destroyed");
    }
    
    /**
     * 根据路由决策获取合适的执行器
     * 这是一个便利方法，将在路由决策后调用
     * 
     * @param targetService 目标服务
     * @return 匹配的服务执行器，如果不存在则返回空
     */
    public Optional<ServiceExecutor> getExecutorByRoutingDecision(String targetService) {
        List<ServiceExecutor> serviceExecutors = getExecutorsByServiceType(targetService);
        if (!serviceExecutors.isEmpty()) {
            // 简单实现：返回第一个匹配的执行器
            // 在实际应用中，可能需要更复杂的负载均衡或故障转移策略
            return Optional.of(serviceExecutors.get(0));
        }
        
        log.warn("No executor found for service type: {}", targetService);
        return Optional.empty();
    }
}